/**模式匹配是我们使用Typescript最有用的特性之一，
 * 我们要实现我们要实现数组的增删改查，数据的提取，
 * 字符串的操作等，都需要用到这个特性。而Typescript 
 * 实现模糊匹配的操作符主要是infer，用于声明局部变量。*/
/**
 * 对数组的处理，通过inter定义内部变量，通过解构赋值加三元运算符返回需要的内容
 * */
type Arr = [1,2,3];
type FirstArr<T extends unknown[]> = T extends [infer First,...unknown[]] ? First : never;
const firstArr: FirstArr<Arr> = 1
let firstArr2: FirstArr<[1]> = undefined
type EndArr<T extends unknown[]> = T extends [...unknown[],infer End] ? End : never;
const endArr: EndArr<Arr> = 3
type RestArr<T extends unknown[]> = T extends [infer First,...infer Rest,infer End] ? Rest : never;
type RestArr2 = RestArr<Arr>;
const restArr: RestArr2 = [2]; // [2]

/**
 * 字符串
 */
type StartWith<T extends string,Prefix extends string> =
  T extends `${Prefix}${string}` ? true : false;
type IsStart = StartWith<'hello word','hello'>; // true
type EndWith<T extends string,End extends string> =
  T extends `${string}${End}` ? true : false;
type IsEnd = EndWith<'hello word','word'>; // true

type Trim<T extends string> =
  T extends `${' ' | '\n' | '\t'}${infer Rest}${' ' | '\n' | '\t'}` ? Rest : never;
type NoTrim = Trim<' hello word '>; // hello word
type Replace<T extends string,From extends string,To extends string> =
  T extends `${infer Prefix}${From}${infer Suffix}` ?
  `${Prefix}${To}${Suffix}` :
  never
type ReplaceStr = Replace<'hellowordxxx','word','world'>
const replaceStr: ReplaceStr = 'helloworldxxx'

/**
 * 函数
 */
type TParameters<T extends ((...arg: any[]) => any)> = 
    T extends (...args: infer Args) => any ? Args : never;
type TestParameter = TParameters<(name: string, age: number) => void>; //[name: string, age: number]

type TReturnType<T extends (...arg: any[]) => any> = 
    T extends (...args: any[]) => infer Return ? Return : never;
type TestReturnType =  TReturnType<(name: string, age: number) => number>; // number